package com.bawei.lib_common.base

import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding

import androidx.lifecycle.Lifecycle
import com.alibaba.android.arouter.launcher.ARouter
import com.bawei.lib_common.R
import com.bawei.lib_common.annotation.Permission

import com.bawei.lib_common.base.state.Empty
import com.bawei.lib_common.base.state.Failed
import com.bawei.lib_common.base.state.Loading
import com.bawei.lib_common.base.state.RequestEvent
import com.bawei.lib_common.base.state.Success
import com.bawei.lib_common.observeWithLifecycle
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.flow.SharedFlow
import java.util.LinkedList
import java.util.Queue

/**
 * @author yaotianxue
 * @description
 * @date 2025/5/12
 */
const val TAG = "BaseActivity"
abstract class BaseActivity<VM: BaseViewModel,VDB: ViewDataBinding>: AppCompatActivity() {
    abstract val mLayoutResId:Int //布局id
    protected lateinit var mBinding:VDB //binding
    //rootView activity---》phoneWindow----》deecorView---》布局UI
    protected lateinit var mRootView:ViewGroup
    //loadingView
    protected var mLoadingView: View? = null


    private lateinit var contentView:View
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 获取根视图
        contentView = findViewById(android.R.id.content)
        //ARouter传值自动注入
        ARouter.getInstance().inject(this) //

        mBinding = DataBindingUtil.setContentView(this,mLayoutResId)
        mBinding.lifecycleOwner = this
        //全局加载状态
        initGlobalView()
        //状态栏
        initStatusBar()
        initView()
        initListener()
        initData()

    }
    /**
     * 控制UI功能隐藏的权限数组
     */
    private lateinit var permissionActionName:Array<String>

    open fun generatePermission(pageName:String):Array<String>{
        return arrayOf()
    }

    override fun onResume() {
        super.onResume()
        //判断是否添加权限管理
//        val permission: Permission = this.javaClass.getAnnotation(Permission::class.java)
//        if (permission != null) {
//            val pageName = permission.page
//            val moduleName = permission.module
//            if (pageName.isEmpty()||moduleName.isEmpty()){
//                throw RuntimeException("need set moduleName and pageName prop")
//            }
//            permissionActionName = generatePermission(pageName)
//            if (::contentView.isInitialized){
//                // 设置所有控件的可见性为VISIBLE
//                setAllViewsVisibility(contentView,permissionActionName)
//            }
//        }
    }
    /**
     * 使用广度优先搜索（BFS）设置视图及其子视图的可见性
     * @param rootView 根视图
     * @param visibility 设置的可见性（VISIBLE、INVISIBLE、GONE）
     */
    private fun setAllViewsVisibility(rootView: View?,btns:Array<String>) {
        if (rootView == null) return

        // 使用队列实现BFS
        val queue: Queue<View> = LinkedList()
        queue.offer(rootView) // 将根视图加入队列

        while (!queue.isEmpty()) {
            val currentView = queue.poll() // 获取队列中的当前视图

            if (currentView.id!=-1 && btns.contains(resources.getResourceEntryName(currentView.id))){
                currentView.visibility = View.GONE
            }


            // 如果当前视图是ViewGroup，将其子视图加入队列
            if (currentView is ViewGroup) {
                val viewGroup = currentView
                for (i in 0 until viewGroup.childCount) {
                    queue.offer(viewGroup.getChildAt(i)) // 将子视图加入队列
                }
            }
        }
    }


    open fun initView(){}
    open fun initListener(){}
    open fun initData(){}

    open fun initStatusBar(){

    }
    open fun showToast(stringRes: String) {
        Snackbar.make(window.decorView, stringRes, Snackbar.LENGTH_LONG).show()
    }

    open fun showToast(view: View?, stringRes: Int) {
        Snackbar.make(view ?: window.decorView, stringRes, Snackbar.LENGTH_LONG).show()
    }

    /**
     * 隐藏键盘
     */
    fun hideKeyboard(view: View) {
        (view.context
            .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?)?.hideSoftInputFromWindow(view.windowToken, 0)
    }
    /**
     * 显示键盘
     */
    fun showSoftKeyBoard(view: View) {
        view.requestFocus()
        view.postDelayed({
            val imm = view.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
            imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
        }, 200)

    }

    fun dismissKeyboard() {
        try {
            val view = window.peekDecorView()
            if (view != null) {
                val im = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
                im.hideSoftInputFromWindow(view.windowToken, 0)
            }
        } catch (e: Exception) {
        }
    }

    /**
     * 全局加载布局
     */
    private fun initGlobalView() {
        mRootView = window.decorView as ViewGroup
        initLoadingView()
    }

    /**
     * 初始化加载中界面
     */
    private fun initLoadingView() {
        if (mLoadingView == null) {
            mLoadingView = layoutInflater.inflate(R.layout.dialog_common_progress, mRootView, false)
            mLoadingView!!.setOnClickListener(View.OnClickListener { v: View? -> })
            setLoadingViewVisible(false)
            mRootView.addView(mLoadingView)
        }
    }

    /**
     * 设置显示或隐藏
     */
    open fun setLoadingViewVisible(show: Boolean, msg: String = "") {
        mLoadingView?.let {
            val textView = it.findViewById<TextView>(R.id.tv_text)
            if (show && msg.isNotEmpty())
                textView.text = msg
            if (show) it.visibility = View.VISIBLE else it.visibility = View.GONE
        }
    }

    // 添加通用的状态监听，这里只做Loading的隐藏，显示和错误消息Toast
    open fun addCommonStateListener(stateListener: SharedFlow<RequestEvent>) {
        stateListener.observeWithLifecycle(this, Lifecycle.State.STARTED) {
            when (it) {
                is Success -> {
                    setLoadingViewVisible(false)
                }
                is Loading -> {
                    setLoadingViewVisible(true)
                }
                is Failed -> {
                    setLoadingViewVisible(false)
                    onLoadFailed(it.message)
                }
                is Empty -> {
                    setLoadingViewVisible(false)
                    showToast("数据为空")
                }

            }
        }
    }
    //失败展示
    open fun onLoadFailed(msg: String) {}

    open val mPageCanBack:Boolean = true //是否可返回
    private var lastPressBack = 0L //上一次点击返回的时间戳
    /**
     * 点击返回处理
     * 1.当前activity是否可返回（A--》B B可返回的 A不可返回）
     *  可返回：默认返回
     *  不可返回：
     *      2.当前activity有无fragment
     *          无：退出app
     *          有：判断fragment是否可返回
     *              可返回：默认返回
     *              不可返回：退出app
     */
    override fun onBackPressed() {
        val timeStamp = System.currentTimeMillis()
        //1.当前activity是否可返回
        if(mPageCanBack){
            Log.d(TAG, "返回上一个activity: ")
            super.onBackPressed()
            return
        }
        //2.当前activity有无fragment
        val fragments = supportFragmentManager.fragments.filterIsInstance<BaseFragment<*,*>>()
        //无fragment：退出app
        if(fragments.isEmpty() && isPressBackToExitApp(timeStamp)){
            Log.d(TAG, "此activity无fragment，关闭app: ")
            super.onBackPressed()
            return
        }
        //有fragment
        for (fragment in fragments){
            if(fragment.isVisible){
                //可返回
                if(fragment.mCanBack){
                    super.onBackPressed()
                    return
                }
                //不可返回:退出app
                if(isPressBackToExitApp(timeStamp)){
                    super.onBackPressed()
                    return
                }
            }
        }

    }

    /**
     * 退出app
     */
    private fun isPressBackToExitApp(timeStamp:Long):Boolean{
        if(lastPressBack == timeStamp){
            return false
        }
        if(timeStamp - lastPressBack < 2000){
            return true
        }else{
            Toast.makeText(this,"再按一次退出", Toast.LENGTH_SHORT).show()
            lastPressBack = timeStamp
            return false
        }

    }




}